﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;

namespace Cyss.Core
{

    /// <summary>
    /// 枚举帮助类
    /// </summary>
    public static class EnumHelper
    {
        private static IList<EnumSelect> EnumSelects = new List<EnumSelect>();

        public static TEnum TryParse<TEnum>(string value) where TEnum : Enum
        {
            object obj;
            var isSuccess = Enum.TryParse(typeof(TEnum), value, true, out obj);
            if (isSuccess)
            {
                return (TEnum)obj;
            }
            return default(TEnum);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="enumObj"></param>
        /// <returns></returns>
        public static EnumSelect GetEnumSelect<TEnum>(this TEnum enumObj) where TEnum : Enum
        {
            var enumSelect = EnumSelects.FirstOrDefault(x => x.Type == enumObj.GetType().FullName);
            if (enumSelect== null)
            {
                enumSelect=enumObj.EnumSelect();
                EnumSelects.Add(enumSelect);
                return enumSelect;
            }
            return enumSelect;
        }

        /// <summary>
        /// 获取枚举项上设置的显示文字
        /// </summary>
        /// <param name="value">被扩展对象</param>
        public static string GetEnumDisplay(object value)
        {
            var enumSelect = EnumSelects.FirstOrDefault(x => x.Type == value.GetType().FullName);
            if (enumSelect == null)
            {
                enumSelect=((Enum)value).EnumSelect();
                EnumSelects.Add(enumSelect);
            }
            var enumSelectItem = enumSelect.SelectItems.FirstOrDefault(x => x.Id == Convert.ToInt32(value));
            if (enumSelectItem == null)
            {
                return value.ToString();
            }
            return enumSelectItem.Text;
        }


        /// <summary>
        /// 获取枚举项上设置的显示文字
        /// </summary>
        /// <param name="value">被扩展对象</param>
        public static string EnumDisplay(this Enum value)
        {
            var enumSelect = EnumSelects.FirstOrDefault(x => x.Type == value.GetType().FullName);
            if (enumSelect == null)
            {
                enumSelect=value.GetEnumSelect();
                EnumSelects.Add(enumSelect);
            }
            var enumSelectItem = enumSelect.SelectItems.FirstOrDefault(x => x.Id == Convert.ToInt32(value));
            if (enumSelectItem == null)
            {
                return value.ToString();
            }
            return enumSelectItem.Text;
        }

        private static EnumSelect EnumSelect(this Enum value, bool language = true)
        {
            var enumSelect = new EnumSelect();
            enumSelect.Type = value.GetType().FullName;
            enumSelect.Language=CultureInfo.CurrentUICulture.Name;
            foreach (var enumValue in Enum.GetValues(value.GetType()))
            {
                EnumSelectItem selectItem = new EnumSelectItem();
                selectItem.Id = Convert.ToInt32(enumValue);
                selectItem.Name=enumValue.ToString();
                selectItem.Text = ((Enum)enumValue).EnumMetadataDisplay();
                selectItem.ResouresKey=$"Enum.{value.GetType().Name}.{enumValue.ToString()}";
                enumSelect.SelectItems.Add(selectItem);
            }
            return enumSelect;
        }

        /// <summary>
        /// 获取枚举项上设置的显示文字
        /// </summary>
        /// <param name="value">被扩展对象</param>
        private static string EnumMetadataDisplay(this Enum value)
        {
            string name = Enum.GetName(value.GetType(), value);
            if (string.IsNullOrEmpty(name))
                return value.ToString();
            var attribute = value.GetType().GetField(name).GetCustomAttributes(
                 typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false)
                 .Cast<System.ComponentModel.DataAnnotations.DisplayAttribute>()
                 .FirstOrDefault();
            if (attribute != null)
                return attribute.Name;

            return value.ToString();
        }

    }
}
